package com.chongyahhh.security.security.configs.verification;

import com.chongyahhh.security.security.common.AuthenticationProcessor;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Author chongyahhh
 * 验证码登录处理器
 */
public class VerificationAuthenticationProcessor implements AuthenticationProcessor {
    private final String USERNAME = "username";
    private final String PASSWORD = "password";
    private final String VERIFICATION_CODE = "verificationCode";

    public VerificationAuthenticationProcessor(){}

    @Override
    public Authentication preAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        String verificationCode = this.obtainVerificationCode(request);
        // 验证码检验
        if(!this.validate(request, verificationCode)){
            throw new VerificationAuthenticationException();
        }
        String username = this.obtainUsername(request);
        String password = this.obtainPassword(request);
        username = (username == null) ? "" : username;
        password = (password == null) ? "" : password;

        username = username.trim();
        // 这个只做登录信息使用
        return new VerificationAuthentication(username, password, null);
    }

    @Override
    public void postAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        // do nothing
    }

    private String obtainPassword(HttpServletRequest request) {
        return request.getParameter(PASSWORD);
    }

    private String obtainUsername(HttpServletRequest request) {
        return request.getParameter(USERNAME);
    }

    private String obtainVerificationCode(HttpServletRequest request) {
        return request.getParameter(VERIFICATION_CODE);
    }

    private boolean validate(HttpServletRequest request, String verificationCode) {
        HttpSession session = request.getSession();
        Object validateCode = session.getAttribute(VERIFICATION_CODE);
        if(validateCode == null) {
            return false;
        }
        // 不分区大小写
        return StringUtils.equalsIgnoreCase((String)validateCode, verificationCode);
    }

    /**
     * 验证码错误异常
     */
    class VerificationAuthenticationException extends AuthenticationException{
        public VerificationAuthenticationException() {
            super("验证码错误");
        }

        public VerificationAuthenticationException(String msg) {
            super(msg);
        }

        public VerificationAuthenticationException(String msg, Throwable t) {
            super(msg, t);
        }
    }
}
